package navtreeimpl

import (
	"fmt"
	"strings"

	contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
	"github.com/grafana/grafana/pkg/services/navtree"
	"github.com/grafana/grafana/pkg/services/sqlstore"

	_ "github.com/go-sql-driver/mysql"
)

type DashboardRow struct {
	ID       string // d.uid
	Text     string // d.title
	FolderID string // d.folder_uid
}

func (s *ServiceImpl) buildCustomNavLinks1(c *contextmodel.ReqContext) []*navtree.NavLink {
	listedProjectNavs := make([]*navtree.NavLink, 0)

	err := s.db.WithDbSession(c.Req.Context(), func(sess *sqlstore.DBSession) error {

		//面板权限
		allCheck := map[string]bool{}
		dashboardCheck := map[string]bool{}
		foldersCheck := map[string]bool{}

		for _, pinfo := range c.SignedInUser.Permissions {
			for _, cinfo := range pinfo {
				for _, detail := range cinfo {
					if strings.Contains(detail, "dashboards:uid") {
						dashboardCheck[strings.Replace(detail, "dashboards:uid:", "", -1)] = true
						allCheck[strings.Replace(detail, "dashboards:uid:", "", -1)] = true
					}
					if strings.Contains(detail, "folders:uid") {
						foldersCheck[strings.Replace(detail, "folders:uid:", "", -1)] = true
						allCheck[strings.Replace(detail, "folders:uid:", "", -1)] = true
						//foldersList = append(foldersList, strings.Replace(detail, "folders:uid:", "", -1))
					}
				}
			}
		}
		foldersList := []string{}
		for folder, _ := range foldersCheck {
			foldersList = append(foldersList, folder)
		}

		dashList := []string{}
		for dash, _ := range dashboardCheck {
			dashList = append(dashList, dash)
		}

		allAccess := map[string]bool{}

		//获取个人有权限的所有
		combinedQuery := `
			WITH RECURSIVE 
			-- 获取指定文件夹下的所有面板
			folder_hierarchy AS (
				SELECT uid, folder_uid, is_folder
				FROM dashboard
				WHERE folder_uid IN ('` + strings.Join(foldersList, "','") + `')
				UNION ALL
				SELECT d.uid, d.folder_uid, d.is_folder
				FROM dashboard d
				INNER JOIN folder_hierarchy fh ON d.folder_uid = fh.uid
			),
			-- 获取特定面板的所有父级文件夹
			parent_folders AS (
				SELECT uid, folder_uid, is_folder
				FROM dashboard
				WHERE uid IN ('` + strings.Join(dashList, "','") + `')
				UNION ALL
				SELECT d.uid, d.folder_uid, d.is_folder
				FROM dashboard d
				JOIN parent_folders pf ON d.uid = pf.folder_uid
			)
			-- 合并所有结果
			SELECT uid AS type FROM folder_hierarchy
			UNION
			SELECT folder_uid
			FROM parent_folders 
			WHERE folder_uid IS NOT NULL
			`

		rows, _ := sess.Query(combinedQuery)
		for _, info := range rows {
			uid := string(info["type"])
			allAccess[uid] = true
		}
		/*
				err := s.updateUserFolderAuth(sess, c.SignedInUser.Login, foldersList)
				if err != nil {
					s.log.Error("更新用户授权目录失败", err)
				}


			//所有有权限的目录，授权所有的节点
			accessDashboardSql := "select uid from grafana.dashboard where folder_uid in ('" + strings.Join(foldersList, "','") + "')"
			rows, _ = sess.Query(accessDashboardSql)
			for _, info := range rows {
				dashboardCheck[string(info["uid"])] = true
			}

			//导航组装
			TopBars, _ := sess.Query(`select uid,title from folder where uid in ("fdgg8zymuuio0f","ddghtwh01cmwwa","ddghtxf63uku8d","cdghty4d4z8xsf","cdgolthgyzgg0a","fdqfycck2oe80a")`)
			projectNavs := make([]*navtree.NavLink, 0)
			for _, TopBar := range TopBars {

				terms := string(TopBar["title"])
				LeftTopMenus, _ := sess.Query(`select title,uid,is_folder,slug,JSON_UNQUOTE(JSON_EXTRACT(data, '$.icon')) as icon from dashboard where folder_uid  = "` + string(TopBar["uid"]) + `" AND title not like "\_%" `)
				for _, LeftTopMen := range LeftTopMenus {
					subNavs := make([]*navtree.NavLink, 0)
					if string(LeftTopMen["is_folder"]) == "1" {
						LeftSubMenus, _ := sess.Query(`select title,uid,is_folder,slug,JSON_UNQUOTE(JSON_EXTRACT(data, '$.description')) as url  from dashboard where folder_uid  = "` + string(LeftTopMen["uid"]) + `" AND title not like "\_%" `)
						for _, LeftSubMenu := range LeftSubMenus {
							if string(LeftSubMenu["is_folder"]) == "1" {
								NodList, _ := sess.Query(`select title,uid,is_folder,slug,JSON_UNQUOTE(JSON_EXTRACT(data, '$.description')) as url  from dashboard where folder_uid  = "` + string(LeftSubMenu["uid"]) + `" AND is_folder = 0 AND title not like "\_%" `)
								Nodes := make([]*navtree.NavLink, 0)
								for _, node := range NodList {
									if _, ok := dashboardCheck[string(node["uid"])]; ok {
										url := s.cfg.AppSubURL + "/d/" + string(node["uid"]) + "/" + string(node["slug"]) + "?orgId=1"
										target := ""
										subcont := ""
										if strings.Contains(string(node["title"]), "[link]") {
											url = string(node["url"])
											target = "_blank"
										}
										if strings.Contains(string(node["title"]), "[inlink]") {
											url = s.cfg.AppSubURL + string(node["url"])
										}
										if strings.Contains(string(node["title"]), "[iframe]") {
											subcont = string(node["url"])
										}
										Nodes = append(Nodes, &navtree.NavLink{
											Text:     string(node["title"]),
											SubTitle: subcont,
											PluginID: terms,
											Id:       string(node["uid"]),
											Target:   target,
											Url:      url,
										})
									}
								}
								if _, ok := foldersCheck[string(LeftSubMenu["uid"])]; ok {
									subNavs = append(subNavs, &navtree.NavLink{
										Text:     string(LeftSubMenu["title"]),
										PluginID: terms,
										Id:       string(LeftSubMenu["uid"]),
										Children: Nodes,
										//Url:      s.cfg.AppSubURL + "/dashboards/f/" + string(LeftSubMenu["uid"]),
										Url: "#",
									})
								}
							} else {
								if _, ok := dashboardCheck[string(LeftSubMenu["uid"])]; ok {
									url := s.cfg.AppSubURL + "/d/" + string(LeftSubMenu["uid"]) + "/" + string(LeftSubMenu["slug"]) + "?orgId=1"
									target := ""
									subcont := ""
									if strings.Contains(string(LeftSubMenu["title"]), "[link]") {
										url = string(LeftSubMenu["url"])
										target = "_blank"
									}
									if strings.Contains(string(LeftSubMenu["title"]), "[inlink]") {
										url = s.cfg.AppSubURL + string(LeftSubMenu["url"])
									}
									if strings.Contains(string(LeftSubMenu["title"]), "[iframe]") {
										subcont = string(LeftSubMenu["url"])
									}
									subNavs = append(subNavs, &navtree.NavLink{
										Text:     string(LeftSubMenu["title"]),
										SubTitle: subcont,
										PluginID: terms,
										Id:       string(LeftSubMenu["uid"]),
										Target:   target,
										Url:      url,
									})
								}
							}
						}
						if _, ok := foldersCheck[string(LeftTopMen["uid"])]; ok {
							icon := "apps"
							if string(LeftTopMen["icon"]) != "" {
								icon = string(LeftTopMen["icon"])
							}
							projectNavs = append(projectNavs, &navtree.NavLink{
								Text:     string(LeftTopMen["title"]),
								PluginID: terms,
								Id:       string(LeftTopMen["uid"]),
								Icon:     icon,
								Children: subNavs,
								//Url:      s.cfg.AppSubURL + "/dashboards/f/" + string(LeftTopMen["uid"]),
								Url: "#",
							})
						}
					} else {
						if _, ok := dashboardCheck[string(LeftTopMen["uid"])]; ok {
							projectNavs = append(projectNavs, &navtree.NavLink{
								Text:     string(LeftTopMen["title"]),
								PluginID: terms,
								Id:       string(LeftTopMen["uid"]),
								Icon:     "home-alt",
								Url:      "#",
								//Url:      s.cfg.AppSubURL + "/d/" + string(LeftTopMen["uid"]),
							})
						}
					}
				}

			}
		*/
		// 收集所有需要的folder_uid，避免多次查询
		//folderUidsToCheck := strings.Join(foldersList, "','")

		// 收集顶部菜单的uid列表
		//topBarUids := []string{"fdgg8zymuuio0f", "ddghtwh01cmwwa", "ddghtxf63uku8d", "cdghty4d4z8xsf", "cdgolthgyzgg0a", "fdqfycck2oe80a"}
		//topBarUidsStr := "'" + strings.Join(topBarUids, "','") + "'"

		// 构建一次性查询所有需要的数据
		sql := `
		WITH RECURSIVE FolderHierarchy AS (
			SELECT 
				uid,
				title,
				folder_uid,
				uid AS top_folder_uid
			FROM 
				dashboard
			WHERE 
				folder_uid IS NULL OR folder_uid = ''
		
			UNION ALL
		
			SELECT 
				d.uid,
				fh.title,
				d.folder_uid,
				fh.top_folder_uid
			FROM 
				dashboard d
			INNER JOIN 
				FolderHierarchy fh ON d.folder_uid = fh.uid
		)
		select
			d.uid as id,
			d.title AS text,
			d.folder_uid as fid,
			fh.title as terms,
			if(d.folder_uid in("fdgg8zymuuio0f","ddghtwh01cmwwa","ddghtxf63uku8d","cdghty4d4z8xsf","cdgolthgyzgg0a","fdqfycck2oe80a"),'top','') as astop
		FROM 
			dashboard d
		LEFT JOIN 
			(SELECT uid, top_folder_uid,title FROM FolderHierarchy) fh 
		ON 
			d.uid = fh.uid where fh.title in ('业务观测','成本运营','业务观测','基础运维','厂内工具') and folder_uid is not null
		`

		// 执行一次性查询
		allResults, err := sess.Query(sql)
		if err != nil {
			s.log.Error("", err)
		}

		//projectNavs := make([]*navtree.NavLink, 0)
		topNav := make(map[string]bool)
		allNavLinks := make(map[string]*navtree.NavLink)
		fmt.Println("1111111111111111111111111111111111111111")
		fmt.Println(len(allResults))

		// 创建所有NavLink对象
		for _, row := range allResults {
			id := string(row["id"])
			text := string(row["text"])
			terms := string(row["terms"])
			astop := string(row["astop"])

			navLink := &navtree.NavLink{
				Id:       id,
				Text:     text,
				PluginID: terms,
				Children: make([]*navtree.NavLink, 0),
			}
			if astop == "top" {
				topNav[id] = true
			}
			fmt.Println(row)

			allNavLinks[id] = navLink
		}

		// 创建子到父的映射关系，用于判断节点是否为根节点
		childToParent := make(map[string]string)

		// 记录所有子项的父项ID
		for _, row := range allResults {
			id := string(row["id"])
			folderID := string(row["fid"])

			if folderID != "" {
				childToParent[id] = folderID
			}
		}

		fmt.Println(topNav)

		// 找出所有根节点（没有父节点的节点）
		for id := range allNavLinks {
			if _, isTopNav := topNav[id]; isTopNav {
				listedProjectNavs = append(listedProjectNavs, allNavLinks[id])
			}
		}

		// 递归构建子节点
		buildChildren(allNavLinks, childToParent)

		//fmt.Println(projectNavs)

		// 将结果组织成易于处理的数据结构
		//dashboardCheck := make(map[string]bool)
		// 查询有权限的dashboard uid列表
		//accessDashboardSql := "select uid from grafana.dashboard where folder_uid in ('" + strings.Join(foldersList, "','") + "')"
		//accessRows, _ := sess.Query(accessDashboardSql)
		//for _, info := range accessRows {
		//	dashboardCheck[string(info["uid"])] = true
		//}

		/*
				// 将查询结果分类整理
				topFolders := make(map[string]map[string][]byte)
				leftMenus := make(map[string][]map[string][]byte)
				subMenus := make(map[string][]map[string][]byte)
				nodes := make(map[string][]map[string][]byte)

				for _, result := range allResults {
					//if _, ok := allAccess[string(result["uid"])]; !ok {
					//	continue
					//}
					itemType := string(result["type"])
					switch itemType {
					case "top_folders":
						uid := string(result["uid"])
						topFolders[uid] = result
					case "left_menus":
						folderUid := string(result["folder_uid"])
						if leftMenus[folderUid] == nil {
							leftMenus[folderUid] = make([]map[string][]byte, 0)
						}
						leftMenus[folderUid] = append(leftMenus[folderUid], result)
					case "sub_menus":
						folderUid := string(result["folder_uid"])
						if subMenus[folderUid] == nil {
							subMenus[folderUid] = make([]map[string][]byte, 0)
						}
						subMenus[folderUid] = append(subMenus[folderUid], result)
					case "nodes":
						folderUid := string(result["folder_uid"])
						if nodes[folderUid] == nil {
							nodes[folderUid] = make([]map[string][]byte, 0)
						}
						nodes[folderUid] = append(nodes[folderUid], result)
					}
				}
				fmt.Println(topFolders)
				fmt.Println(leftMenus)
				fmt.Println(subMenus)
				fmt.Println(nodes)

				// 组装导航
				projectNavs := make([]*navtree.NavLink, 0)

				// 按照原有的排序处理顶级菜单
				for _, topBarUid := range topBarUids {
					topBar, exists := topFolders[topBarUid]
					if !exists {
						continue
					}
					fmt.Println(string(topBar["title"]))

					terms := string(topBar["title"])
					leftTopMenusList := leftMenus[topBarUid]
					fmt.Println(leftTopMenusList)

					for _, leftTopMenu := range leftTopMenusList {
						subNavs := make([]*navtree.NavLink, 0)
						leftTopMenuUid := string(leftTopMenu["uid"])

						if string(leftTopMenu["is_folder"]) == "1" {
							// 处理子菜单
							leftSubMenusList := subMenus[leftTopMenuUid]
							for _, leftSubMenu := range leftSubMenusList {
								leftSubMenuUid := string(leftSubMenu["uid"])

								if string(leftSubMenu["is_folder"]) == "1" {
									// 处理第三级节点
									nodesList := nodes[leftSubMenuUid]
									nodesNavs := make([]*navtree.NavLink, 0)

									for _, node := range nodesList {
										nodeUid := string(node["uid"])
										//if _, ok := dashboardCheck[nodeUid]; ok {
										url := s.cfg.AppSubURL + "/d/" + nodeUid + "/" + string(node["slug"]) + "?orgId=1"
										target := ""
										subcont := ""

										if strings.Contains(string(node["title"]), "[link]") {
											url = string(node["url"])
											target = "_blank"
										}
										if strings.Contains(string(node["title"]), "[inlink]") {
											url = s.cfg.AppSubURL + string(node["url"])
										}
										if strings.Contains(string(node["title"]), "[iframe]") {
											subcont = string(node["url"])
										}

										nodesNavs = append(nodesNavs, &navtree.NavLink{
											Text:     string(node["title"]),
											SubTitle: subcont,
											PluginID: terms,
											Id:       nodeUid,
											Target:   target,
											Url:      url,
										})
										//}
									}

									if _, ok := foldersCheck[leftSubMenuUid]; ok {
										subNavs = append(subNavs, &navtree.NavLink{
											Text:     string(leftSubMenu["title"]),
											PluginID: terms,
											Id:       leftSubMenuUid,
											Children: nodesNavs,
											Url:      "#",
										})
									}
								} else {
									// 处理普通子菜单项
									//if _, ok := dashboardCheck[leftSubMenuUid]; ok {
									url := s.cfg.AppSubURL + "/d/" + leftSubMenuUid + "/" + string(leftSubMenu["slug"]) + "?orgId=1"
									target := ""
									subcont := ""

									if strings.Contains(string(leftSubMenu["title"]), "[link]") {
										url = string(leftSubMenu["url"])
										target = "_blank"
									}
									if strings.Contains(string(leftSubMenu["title"]), "[inlink]") {
										url = s.cfg.AppSubURL + string(leftSubMenu["url"])
									}
									if strings.Contains(string(leftSubMenu["title"]), "[iframe]") {
										subcont = string(leftSubMenu["url"])
									}

									subNavs = append(subNavs, &navtree.NavLink{
										Text:     string(leftSubMenu["title"]),
										SubTitle: subcont,
										PluginID: terms,
										Id:       leftSubMenuUid,
										Target:   target,
										Url:      url,
									})
									//}
								}
							}

							//if _, ok := foldersCheck[leftTopMenuUid]; ok {
							icon := "apps"
							if string(leftTopMenu["icon"]) != "" {
								icon = string(leftTopMenu["icon"])
							}

							projectNavs = append(projectNavs, &navtree.NavLink{
								Text:     string(leftTopMenu["title"]),
								PluginID: terms,
								Id:       leftTopMenuUid,
								Icon:     icon,
								Children: subNavs,
								Url:      "#",
							})
							//}
						} else {
							// 处理顶层非文件夹项
							//if _, ok := dashboardCheck[leftTopMenuUid]; ok {
							projectNavs = append(projectNavs, &navtree.NavLink{
								Text:     string(leftTopMenu["title"]),
								PluginID: terms,
								Id:       leftTopMenuUid,
								Icon:     "home-alt",
								Url:      "#",
							})
							//}
						}
					}
				}

				//fmt.Println(projectNavs)


			// 重新排列projectNavs
			for _, project := range projectNavs {
				sortedSubNavs := make([]*navtree.NavLink, 0)
				for _, subNav := range project.Children {
					sortedNodeNavs := append([]*navtree.NavLink(nil), subNav.Children...)
					sort.Slice(sortedNodeNavs, func(i, j int) bool {
						return sortedNodeNavs[i].Text < sortedNodeNavs[j].Text
					})
					subNav.Children = sortedNodeNavs
					sortedSubNavs = append(sortedSubNavs, subNav)
				}
				sort.Slice(sortedSubNavs, func(i, j int) bool {
					return sortedSubNavs[i].Text < sortedSubNavs[j].Text
				})
				project.Children = sortedSubNavs
				listedProjectNavs = append(listedProjectNavs, project)
			}
			sort.Slice(listedProjectNavs, func(i, j int) bool {
				return listedProjectNavs[i].Text < listedProjectNavs[j].Text
			})

			// 替换标题中的 [0001]，用于排序
			pattern := "\\[\\d+\\]"
			re := regexp.MustCompile(pattern)
			for _, project := range listedProjectNavs {
				project.Text = re.ReplaceAllString(project.Text, "")
				project.Text = strings.Replace(project.Text, "[link]", "", -1)
				project.Text = strings.Replace(project.Text, "[inlink]", "", -1)
				for _, subNav := range project.Children {
					subNav.Text = re.ReplaceAllString(subNav.Text, "")
					subNav.Text = strings.Replace(subNav.Text, "[link]", "", -1)
					subNav.Text = strings.Replace(subNav.Text, "[inlink]", "", -1)
					for _, nodeNav := range subNav.Children {
						nodeNav.Text = re.ReplaceAllString(nodeNav.Text, "")
						nodeNav.Text = strings.Replace(nodeNav.Text, "[link]", "", -1)
						nodeNav.Text = strings.Replace(nodeNav.Text, "[inlink]", "", -1)
					}
				}
			}
		*/
		return nil
	})
	if err != nil {
		s.log.Error("Get Custom Nav Error", "err", err)
	}
	return listedProjectNavs

}

// buildChildren 递归构建NavLink的子节点
func buildChildren1(allNavLinks map[string]*navtree.NavLink, childToParent map[string]string) {
	// 创建父到子的映射关系
	parentToChildren := make(map[string][]string)

	for childID, parentID := range childToParent {
		if _, exists := parentToChildren[parentID]; !exists {
			parentToChildren[parentID] = make([]string, 0)
		}
		parentToChildren[parentID] = append(parentToChildren[parentID], childID)
	}

	// 使用递归函数填充子节点
	var fillChildren func(string)
	fillChildren = func(nodeID string) {
		// 获取当前节点的所有子节点ID
		childIDs, hasChildren := parentToChildren[nodeID]
		if !hasChildren {
			return // 没有子节点，结束递归
		}

		// 获取当前节点
		node := allNavLinks[nodeID]

		// 清空子节点列表，避免重复添加
		node.Children = make([]*navtree.NavLink, 0, len(childIDs))

		// 添加所有子节点
		for _, childID := range childIDs {
			childNode := allNavLinks[childID]
			node.Children = append(node.Children, childNode)

			// 递归处理子节点的子节点
			fillChildren(childID)
		}
	}

	// 对所有节点应用递归函数
	for nodeID := range allNavLinks {
		fillChildren(nodeID)
	}
}

func (s *ServiceImpl) updateUserFolderAuth1(sess *sqlstore.DBSession, login string, foldersList []string) error {
	if len(foldersList) > 0 {
		// 开始事务
		err := sess.Begin()
		if err != nil {
			s.log.Error("Failed to begin transaction", "err", err)
			return err
		}

		// 确保事务在错误时回滚
		defer func() {
			if p := recover(); p != nil {
				sess.Rollback()
				//panic(p) // 重新触发 panic
			} else if err != nil {
				sess.Rollback()
			} else {
				err = sess.Commit()
				if err != nil {
					s.log.Error("Failed to commit transaction", "err", err)
				}
			}
		}()

		var valueStrings []string
		var valueArgs []interface{}
		for _, folder := range foldersList {
			valueStrings = append(valueStrings, "(?, ?, 1)")
			valueArgs = append(valueArgs, login, folder)
		}
		insertSQL := `INSERT INTO user_folder_auth (login, folder_uid, update_flag) VALUES ` + strings.Join(valueStrings, ",") + ` ON DUPLICATE KEY UPDATE update_flag = VALUES(update_flag)`

		args := append([]interface{}{insertSQL}, valueArgs...)
		s.log.Debug("Insert User Folder Auth SQL", "sql", args)
		_, err = sess.Exec(args...)
		if err != nil {
			s.log.Error("Insert User Folder Auth Error", "err", err)
			return err
		}

		deleteSQL := `DELETE FROM user_folder_auth WHERE login = ? AND update_flag = 0`
		_, err = sess.Exec(deleteSQL, login)
		if err != nil {
			s.log.Error("Delete Old User Folder Auth Error", "err", err)
			return err
		}

		updateSQL := `UPDATE user_folder_auth SET update_flag = 0 WHERE login = ?`
		_, err = sess.Exec(updateSQL, login)
		if err != nil {
			s.log.Error("Update User Folder Auth Error", "err", err)
			return err
		}
	}
	return nil
}
